const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");

// 样式单独打包
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const isDev = process.env.NODE_ENV == "development";

// 输出
const outDir = path.resolve(__dirname, "../dist");
const outDllDir = path.resolve(outDir, "dll");


const minicssLoader = {
  loader: MiniCssExtractPlugin.loader,
  options: {
    publicPath: (resourcePath, context) => {
      return path.relative(path.dirname(resourcePath), context) + "../";
    },
    esModule: true,
  },
};

const postcssLoader = {
  loader: "postcss-loader",
  options: {
    plugins: [require("autoprefixer")],
  },
};

const px2remLoader = {
  loader: "px2rem-loader",
  options: {
    remUni: 75, // 默认/75
    remPrecision: 8, //精度8位
  },
};

const babelLoader = {
  loader: "babel-loader",
  options: {
    presets: ["@babel/preset-env", "@babel/preset-react"],
    plugins: [
      "@babel/plugin-transform-runtime",
      "@babel/plugin-proposal-class-properties",
      "@babel/plugin-syntax-dynamic-import",
      ["import", { libraryName: "antd", libraryDirectory: "es", style: "css" }], // ant 按需打包
    ],
  },
};

const urlLoader = {
  loader: "url-loader", //文件转换为base64 URI
  options: {
    limit: 8192,
    outputPath: "assets/images",
    publicPath: "/assets/images",
    name: "[name].[ext]",
  },
};

const threadLoader = {
  loader: "thread-loader",
};

const optimization={
  splitChunks: {
    chunks: "all", //默认作用于异步chunk，值为all/initial/async
    minSize: 30000, //默认值是30kb,代码块的最小尺寸
    minChunks: 1, //被多少模块共享,在分割之前模块的被引用次数
    maxAsyncRequests: 5, //按需加载最大并行请求数量
    maxInitialRequests: 3, //一个入口的最大并行请求数量
    name: true, //打包后的名称，默认是chunk的名字通过分隔符（默认是～）分隔开，如vendor~
    automaticNameDelimiter: "~", //默认webpack将会使用入口名和代码块的名称生成命名,比如 'vendors~main.js'
    cacheGroups: {
      //设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例
      vendors: {
        name: "vendors",
        chunks: "initial",
        test: /node_modules/, //条件
        priority: -10, ///优先级，一个chunk很可能满足多个缓存组，会被抽取到优先级高的缓存组中,为了能够让自定义缓存组有更高的优先级(默认0),默认缓存组的priority属性为负值.
      },
      commons: {
        chunks: "initial",
        minSize: 0, //最小提取字节数
        minChunks: 2, //最少被几个chunk引用
        priority: -20,
        reuseExistingChunk: true, //    如果该chunk中引用了已经被抽取的chunk，直接引用该chunk，不会重复打包代码
      },
    },
  },

};

const config = {
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: outDir,
    filename: "js/[name].[contentHash].js",
    publicPath: "/", // index.html引入路径,
    sourceMapFilename: "sourceMap/[file].map",
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "..", "src"),
      "~": path.resolve(__dirname, "..", "node_modules"),
    },
    extensions: [".js", ".json"],
  },
  // optimization,
  module: {
    rules: [
      {
        test: /\.css$/, // css处理器
        exclude: /node_modules/,
        use: [
          minicssLoader,
          //'style-loader',
          "css-loader",
          postcssLoader,
          // px2remLoader,
        ],
      },
      {
        test: /\.less$/, // less处理器
        exclude: /node_modules/,
        use: [
          minicssLoader,
          // 'style-loader',
          "css-loader",
          postcssLoader,
          // px2remLoader,
          "less-loader",
        ],
      },
      {
        test: /\.(css|less)$/, //三方框架样式打包
        include: /node_modules|antd\.css/,
        use: [minicssLoader, "css-loader"],
      },
      {
        test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
        use: [urlLoader],
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        enforce: "pre",
        use: [threadLoader, babelLoader],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      favicon: path.resolve(__dirname, "../src/assets/images/favicon.ico"),
    }),
    new CleanWebpackPlugin({
      //  dry: true,//模拟删除，不真正删除
      //  verbose: true,
      cleanOnceBeforeBuildPatterns: ["**/*", "!dll", "!dll/**/*"], //dll不删除
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.join(outDllDir,'react', "react_manifest.json")),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.join(outDllDir,'test', "test_manifest.json")),
    }),
    new HardSourceWebpackPlugin({
      cachePrune: {
        maxAge: 2 * 24 * 60 * 60 * 1000,//缓存最大2 days
        sizeThreshold: 500 * 1024 * 1024//缓存最大500 MB
      },
    }),
    new MiniCssExtractPlugin({
      filename: "assets/css/[name].[contentHash]:8].css",
      chunkFilename: "assets/css/[name].[contentHash:8].css",
    }),
  ],
};


module.exports=config;